package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.cache.TsCache;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.atguigu.tingshu.vo.album.AlbumStatVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.type.CollectionLikeType;
import com.tencentcloudapi.ame.v20190916.models.Album;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Nullable;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {



	@Autowired
	private AlbumInfoMapper albumInfoMapper;

	@Autowired
	private AlbumStatMapper albumStatMapper;

	@Autowired
	private AlbumAttributeValueMapper albumAttributeValueMapper;

	@Autowired
	private RabbitService rabbitService;

	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private RedissonClient redissonClient;


	@Override
	@TsCache(prefix = "statVo:")
	public AlbumStatVo getAlbumStatVo(Long albumId) {
		return albumInfoMapper.selectAlbumStatVo(albumId);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public IPage<AlbumListVo> findUserAlbumPage(Page<AlbumListVo> albumListVoPage, AlbumInfoQuery albumInfoQuery) {
		//	查询数据有专辑基本信息+专辑统计信息; album_info; album_stat;
		return albumInfoMapper.selectUserAlbumPage(albumListVoPage,albumInfoQuery);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void removeAlbumInfo(Long albumId) {
		//		album_attribute_value
		//		album_info
		//		album_sta
		albumInfoMapper.deleteById(albumId);
		//	album_attribute_value;
		//	delete from album_attribute_value where album_id = ? and is_delete=0; 物理删除;
		//	update album_attribute_value set is_delete=1 where album_id = ? and is_delete=0; 逻辑删除
		albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId,albumId));
		//album_stat
		albumStatMapper.delete(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId,albumId));
	}

	@Override
	@TsCache(prefix = RedisConstant.ALBUM_INFO_PREFIX)
	public AlbumInfo getAlbumInfo(Long albumId) {

//		String datakey = RedisConstant.ALBUM_INFO_PREFIX+albumId;
//		try {
//			AlbumInfo albumInfo =(AlbumInfo)this.redisTemplate.opsForValue().get(datakey);
//			if (null == albumInfo){
//				String lockKey = RedisConstant.ALBUM_LOCK_SUFFIX+albumId;
//				RLock lock = redissonClient.getLock(lockKey);
//				lock.lock();
//				try {
//					 albumInfo =(AlbumInfo)this.redisTemplate.opsForValue().get(datakey);
//					 if (null!=albumInfo){
//						 log.info("查询缓存");
//						 return albumInfo;
//					 }
//					albumInfo = getAlbumInfoDB(albumId);
//					 log.info("查询数据库");
//					if (null == albumInfo){
//						this.redisTemplate.opsForValue().set(datakey,new AlbumInfo(),10, TimeUnit.MINUTES);
//						return new AlbumInfo();
//					}
//					this.redisTemplate.opsForValue().set(datakey,albumInfo,RedisConstant.ALBUM_TIMEOUT,TimeUnit.SECONDS);
//					return albumInfo;
//				} catch (Exception e) {
//					throw new RuntimeException(e);
//				} finally {
//					lock.unlock();
//				}
//			}else{
//				return albumInfo;
//			}
//		} catch (RuntimeException e) {
//			log.info("查询缓存");
//			System.out.println(e.getMessage());
//		}
		return getAlbumInfoDB(albumId);
	}

	private @Nullable AlbumInfo getAlbumInfoDB(Long albumId) {
		AlbumInfo albumInfo = this.getById(albumId);
		//	查询专辑对应属性标签数据
		if (null!=albumInfo){
			//	查询专辑Id 对应的属性集合 select * from album_attribute_value where album_id = ? and is_deleted=0;
			albumInfo.setAlbumAttributeValueVoList(albumAttributeValueMapper.selectList
					(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId)));

		}
		return albumInfo;
	}

	@Override
	public void updateAlbumInfo(Long albumId, AlbumInfoVo albumInfoVo) {
		//album_info
		AlbumInfo albumInfo = new AlbumInfo();
		//属性拷贝
		BeanUtils.copyProperties(albumInfoVo,albumInfo);
		albumInfo.setId(albumId);
		//更新数据
		albumInfoMapper.updateById(albumInfo);
		//	album_attribute_value 先删除，再新增!
		albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId,albumId));
		//album_attribute_value 添加数据
		List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
		//判断
		if (!CollectionUtils.isEmpty(albumAttributeValueVoList)){
			for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
				//创建对象
				AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
				//属性拷贝
				BeanUtils.copyProperties(albumAttributeValueVo,albumAttributeValue);
				//执行了insert 方法。所以通过type = IdType.AUTO 属性配置，就能够获取到主键自增
				albumAttributeValue.setAlbumId(albumInfo.getId());
				//	保存数据：insert into album_attribute_value values(?,?,?); insert into album_attribute_value values(?,?,?);
				//	insert into album_attribute_value values (?,?,?) (?,?,?) (?,?,?) mybatis-plus 的批量插入！
				albumAttributeValueMapper.insert(albumAttributeValue);
			}


		}
		if("1".equals(albumInfoVo.getIsOpen())){
			//上架
			rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_UPPER,albumId);
			RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
			bloomFilter.add(albumId);


		}else {
			//下架
			rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_LOWER,albumId);

		}

	}

	@Override
	public List<AlbumInfo> findUserAllAlbumList(long userId) {
		//	select * from album_info where user_id = 1;
		//	select id, album_title from album_info where user_id = 1;
		//	List<AlbumInfo> albumInfoList = albumInfoMapper.selectList(new LambdaQueryWrapper<AlbumInfo>().eq(AlbumInfo::getUserId, userId).select(AlbumInfo::getId, AlbumInfo::getAlbumTitle).orderByDesc(AlbumInfo::getId))
		//	前端应该传递pageNo,pageSize;
		Page<AlbumInfo> albumInfoPage = new Page<>(1, 10);
		Page<AlbumInfo> infoPage = albumInfoMapper.selectPage(albumInfoPage, new LambdaQueryWrapper<AlbumInfo>().eq(AlbumInfo::getUserId, userId)
				.select(AlbumInfo::getId, AlbumInfo::getAlbumTitle).orderByDesc(AlbumInfo::getId));
		//建立索引:album_title
		return infoPage.getRecords();

	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveAlbumInfo(AlbumInfoVo albumInfoVo, long userId) {
		//  album_info
		AlbumInfo albumInfo = new AlbumInfo();
		//	属性赋值; 属性拷贝 - 属性一致的；将属性数据平移！
		BeanUtils.copyProperties(albumInfoVo,albumInfo);
		//	userId; tracks_for_free; status
		albumInfo.setUserId(userId);
		//	免费试听集数：
		//	判断当前专辑的类型;
		if(!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfoVo.getPayType())){
			//	说明付费专辑: 都应该有试听集数;
			albumInfo.setTracksForFree(5);
		}
		albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
		albumInfoMapper.insert(albumInfo);
		//  album_attribute_value
		List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
		//	判断
		if (!CollectionUtils.isEmpty(albumAttributeValueVoList)){
			for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
				//	创建对象
				AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
				//	属性拷贝：
				BeanUtils.copyProperties(albumAttributeValueVo,albumAttributeValue);
				//	因为53行执行了insert 方法。所以通过type = IdType.AUTO 属性配置，就能够获取到主键自增的id
				albumAttributeValue.setAlbumId(albumInfo.getId());
				//	保存数据：insert into album_attribute_value values(?,?,?); insert into album_attribute_value values(?,?,?);
				//	insert into album_attribute_value values (?,?,?) (?,?,?) (?,?,?) mybatis-plus 的批量插入！
				albumAttributeValueMapper.insert(albumAttributeValue);
			}

		}
		//  album_stat
		this.saveAlbumStat(albumInfo.getId(),SystemConstant.ALBUM_STAT_PLAY);
		this.saveAlbumStat(albumInfo.getId(),SystemConstant.ALBUM_STAT_SUBSCRIBE);
		this.saveAlbumStat(albumInfo.getId(),SystemConstant.ALBUM_STAT_BROWSE);
		this.saveAlbumStat(albumInfo.getId(),SystemConstant.ALBUM_STAT_COMMENT);

		if("1".equals(albumInfoVo.getIsOpen())){
			//上架
			rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_UPPER,albumInfo.getId());

			RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
			bloomFilter.add(albumInfo.getId());

		}

	}

	public void saveAlbumStat(Long albumId,String statPlay){
		//保存数据
		AlbumStat albumStat = new AlbumStat();
		albumStat.setAlbumId(albumId);
		albumStat.setStatType(statPlay);
		albumStat.setStatNum(new Random().nextInt(10000000));
		albumStatMapper.insert(albumStat);

	}

}
